/**
 * Copyright (C), 2015-2019, XXX���޹�˾
 * FileName: ActivityTurntableDrawServiceImpl
 * Author:   zhouheng
 * Date:     2019/4/14 10:44
 * Description: ת�̳齱ʵ����
 * History:
 * <author>          <time>          <version>          <desc>
 * ��������           �޸�ʱ��           �汾��              ����
 */
package com.activity.services;

import com.activity.dal.entitys.ActDrawAward;
import com.activity.dal.entitys.ActDrawAwardItem;
import com.activity.dal.persistence.ActDrawAwardItemMapper;
import com.activity.dal.persistence.ActDrawAwardMapper;
import com.activity.draw.bean.ActivityTurntableDrawReq;
import com.activity.draw.bean.AwardDrawRecordBean;
import com.activity.draw.common.ResultResp;
import com.activity.draw.common.ReturnCodeEnum;
import com.activity.draw.service.ActivityTurntableDrawService;
import com.activity.services.processor.ActivityDrawContext;
import com.activity.services.processor.ActivityTurntableDrawProxy;
import com.activity.services.processor.constants.DrawContants;
import com.activity.services.processor.constants.RedisKeyManager;
import com.activity.services.processor.exception.RewardException;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.config.annotation.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 装盘抽奖实现类
 * @author zhouheng
 * @create 2019/4/14
 * @since 1.0.0
 */


@Service
@Slf4j
public class ActivityTurntableDrawServiceImpl implements ActivityTurntableDrawService{

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ActDrawAwardItemMapper actDrawAwardItemMapper;

    @Autowired
    private ActDrawAwardMapper actDrawAwardMapper;

    @Autowired
    private ActivityTurntableDrawProxy activityTurntableDrawProxy;

    @PostConstruct
    public void initDrawData() throws Exception {

        // 将奖项数据存储到redis中
        List<ActDrawAwardItem> awardItems = actDrawAwardItemMapper.queryAwardItem();
        if(CollectionUtils.isEmpty(awardItems)){
            throw new Exception("奖品数据未创建，初始化失败");
        }

        redisTemplate.opsForValue().set(DrawContants.DRAW_ITEM,awardItems);
        redisTemplate.expire(DrawContants.DRAW_ITEM, DrawContants.EXPIRE_TIME, TimeUnit.DAYS);

        for (ActDrawAwardItem actDrawAwardItem : awardItems){
            ActDrawAward actDrawAward = actDrawAwardMapper.queryAwardById(actDrawAwardItem.getAwardId());
            redisTemplate.opsForValue().set(RedisKeyManager.getAwardRedisKey(actDrawAward), actDrawAward);
            redisTemplate.expire(RedisKeyManager.getAwardRedisKey(actDrawAward),DrawContants.EXPIRE_TIME,TimeUnit.DAYS);
            // TODO 如果奖品是有数量限制的，比如京东券 ，那么针对这类的奖品需要放到队列中
            // redisTemplate.opsForList().leftPush()
        }
    }

    public ResultResp<AwardDrawRecordBean> doDraw(ActivityTurntableDrawReq activityTurntableDrawReq) {
        ResultResp<AwardDrawRecordBean> recordBeanResultResp = new ResultResp<AwardDrawRecordBean>();

        try {
            // 1. 校验是否正在抽奖
            checkDrawParams(activityTurntableDrawReq);

            ActivityDrawContext activityDrawContext = new ActivityDrawContext();
            activityDrawContext.setActivityTurntableDrawReq(activityTurntableDrawReq);

            activityTurntableDrawProxy.doDrawForProxy(activityDrawContext);
            AwardDrawRecordBean awardDrawRecordBean = new AwardDrawRecordBean();
            awardDrawRecordBean.setId(activityDrawContext.getActDrawAwardItem().getId());
            awardDrawRecordBean.setUid(activityDrawContext.getActDrawAwardItem().getLevel());
            awardDrawRecordBean.setName(activityDrawContext.getActDrawAwardItem().getItemName());

            recordBeanResultResp.setResult(awardDrawRecordBean);
            recordBeanResultResp.setReturnCodeEnum(ReturnCodeEnum.SUCCESS);
        }catch (Exception e){
            log.error("抽奖失败!", e);
            recordBeanResultResp.setReturnCodeEnum(ReturnCodeEnum.SYSTEM_ERROR);
        }finally {
            log.info("抽奖请求{},响应{}", activityTurntableDrawReq, recordBeanResultResp);
            // 清除正在抽奖标志cache
            cleanRedisCache(activityTurntableDrawReq);
        }

        return recordBeanResultResp;
    }

    /**
     * @description: 清除正在抽奖标志cache
     * @date: 2019/4/15 22:37
     * @author:zhouheng
     */
    private void cleanRedisCache(ActivityTurntableDrawReq activityTurntableDrawReq) {
        try {
            redisTemplate.delete(RedisKeyManager.getDrawingRedisKey(activityTurntableDrawReq));
        } catch (Exception e) {
            log.error("清除key[" +RedisKeyManager.getDrawingRedisKey(activityTurntableDrawReq)+ "]异常", e);
        }
    }

    /**
     * @description: 查询剩余抽奖次数
     * @date: 2019/4/15 22:38
     * @author:zhouheng
     */
    public Integer queryRemainDrawCount(ActivityTurntableDrawReq activityTurntableDrawReq) {
        return null;
    }

    /**
     * @description: 检查请求参数
     * @date: 2019/4/15 22:49
     * @author:zhouheng
     */
    private void checkDrawParams(ActivityTurntableDrawReq activityTurntableDrawReq) {
        if ((null == activityTurntableDrawReq.getUid())) {
            throw new RewardException("uid不能为空");
        }

        Object value = redisTemplate.opsForValue().get(RedisKeyManager.getDrawingRedisKey(activityTurntableDrawReq));

        if(value != null && DrawContants.ISEXIST.EXIST.getValue().equals(value.toString())){
            throw new RewardException("上一次抽奖还未结束");
        }

        //设置正在抽奖
        redisTemplate.opsForValue().set(RedisKeyManager.getDrawingRedisKey(activityTurntableDrawReq),
                DrawContants.ISEXIST.EXIST.getValue());
        redisTemplate.expire(RedisKeyManager.getDrawingRedisKey(activityTurntableDrawReq),
                DrawContants.EXPIRE_TIME,TimeUnit.DAYS);
    }
}